/**
 * 软件IIC通信库实现
 */

#include "soft_i2c.h"

void soft_i2c_set_sda(i2c_ops_t *i2c_ops,uint8_t set)
{
	(set == 0) ? (i2c_ops->sda_low()) : (i2c_ops->sda_high());
}

uint8_t soft_i2c_read_ck(i2c_ops_t *i2c_ops)
{
	volatile uint8_t ck;
	i2c_ops->scl_low();
	i2c_ops->sda_high();
	i2c_ops->delay(i2c_ops->delay_x);
	i2c_ops->scl_high();
	i2c_ops->delay(i2c_ops->delay_x);
	ck = i2c_ops->sda_read();
	return ck;
}

void soft_i2c_set_ck(i2c_ops_t *i2c_ops,uint8_t set)
{
	
}

void soft_i2c_start(i2c_ops_t *i2c_ops)
{
	i2c_ops->scl_high();
	i2c_ops->sda_high();
	i2c_ops->sda_low();
	i2c_ops->delay(i2c_ops->delay_x);
	i2c_ops->scl_low();
}

void soft_i2c_stop(i2c_ops_t *i2c_ops)
{
	i2c_ops->scl_low();
	i2c_ops->sda_low();
	i2c_ops->scl_high();
	i2c_ops->delay(i2c_ops->delay_x);
	i2c_ops->sda_high();
}

void __soft_i2c_writeByte__(i2c_ops_t *i2c_ops,uint8_t data)
{
	volatile int8_t i;
	for(i = 7;i >= 0;i--)
	{
		i2c_ops->scl_low();
		soft_i2c_set_sda(i2c_ops,(data & (0x01 << i)) != 0);
		i2c_ops->delay(i2c_ops->delay_x);
		i2c_ops->scl_high();
		i2c_ops->delay(i2c_ops->delay_x);
	}
}

void __soft_i2c_readByte__(i2c_ops_t *i2c_ops,uint8_t *data)
{
	volatile int8_t i;
	for(i = 7;i >= 0;i--)
	{
		i2c_ops->scl_low();
		i2c_ops->delay(i2c_ops->delay_x);
		i2c_ops->scl_high();
		i2c_ops->delay(i2c_ops->delay_x);
		*data |= i2c_ops->sda_read() << i;
	}
}

uint8_t soft_i2c_writeByte(i2c_ops_t *i2c_ops,uint8_t data)
{
	volatile uint8_t ck;
	soft_i2c_start(i2c_ops);
	__soft_i2c_writeByte__(i2c_ops,data);
	ck = soft_i2c_read_ck(i2c_ops);
	soft_i2c_stop(i2c_ops);
	return ck;
}

void soft_i2c_readByte(i2c_ops_t *i2c_ops,uint8_t slave_address,uint8_t *data)
{
	volatile int8_t i,ck;
	*data = 0;
	soft_i2c_start(i2c_ops);
	__soft_i2c_writeByte__(i2c_ops,(slave_address << 7) | 0x01);
	__soft_i2c_readByte__(i2c_ops,data);
	soft_i2c_stop(i2c_ops);
}
